package com.wulis.common.utils;

import static com.wulis.common.constant.GlobalConstant.TOKEN_EXPIRATION;

import java.io.InputStream;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import com.alibaba.fastjson.JSONObject;
import com.wulis.config.security.AuthUserDetails;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;

/**
 * @author WuliBao
 */
@Slf4j
public class JwtTokenUtil {
    
    /**
     * 私钥
     */
    private static PrivateKey privateKey = null;
    
    /**
     * 公钥
     */
    private static PublicKey publicKey = null;
    
    // 将证书文件里边的私钥公钥拿出来
    static {
        try {
            // 寻找证书文件
            InputStream inputStream =
                Thread.currentThread().getContextClassLoader().getResourceAsStream("auth-jwt.jks");
            // 证书密码
            String keyPassword = "WuliBao";
            // java key store 固定常量
            KeyStore keyStore = KeyStore.getInstance("JKS");
            keyStore.load(inputStream, keyPassword.toCharArray());
            // jwt 为 命令生成整数文件时的别名
            privateKey = (PrivateKey)keyStore.getKey("auth-jwt", keyPassword.toCharArray());
            publicKey = keyStore.getCertificate("auth-jwt").getPublicKey();
        }
        catch (Exception e) {
            log.error("获取证书信息失败",e);
        }
    }
    
    /**
     * 解析token
     *
     * @param token token
     * @return String
     */
    public static AuthUserDetails parseToken(String token) {
        AuthUserDetails authUserDetails = null;
        if (token != null) {
            try {
                // 解析token
                Claims claims = Jwts.parserBuilder().setSigningKey(publicKey).build().parseClaimsJws(token).getBody();
                // token转对象AuthUserDetails
                authUserDetails = JSONObject.parseObject(JSONObject.toJSONString(claims), AuthUserDetails.class);
            }
            // 捕获解析异常
            catch (JwtException e) {
                log.warn(e.getMessage(),e);
            }
        }
        return authUserDetails;
    }
    
    /**
     * 生成token
     *
     * @param authUserDetails authUserDetails
     * @return String
     */
    public static String generateToken(AuthUserDetails authUserDetails) {
        // 设置头部信息
        Map<String, Object> header = new HashMap<>(1);
        header.put("typ", "JWT");
        header.put("alg", SignatureAlgorithm.RS256.getValue());
        // 设置PayLoad信息
        Map<String, Object> payLoad = JSONObject.parseObject(JSONObject.toJSONString(authUserDetails));
        // 设置过期时间为TOKEN_EXPIRATION配置
        LocalDateTime expirationAt = LocalDateTime.now().plusHours(TOKEN_EXPIRATION);
        return Jwts.builder()
            .setHeader(header)
            .setClaims(payLoad)
            .setExpiration(Date.from(expirationAt.atZone(ZoneId.systemDefault()).toInstant()))
            .signWith(privateKey, SignatureAlgorithm.RS256)
            .compact();
    }
    
}
